iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0

前情提要

「好了,你已經說明了什麼是防禦魔法,又給了我兩把利器 - 鏟子,這些跟防禦魔法有什麼關係?」

「我早就料到你會這麼問了!昨天不是教了怎麼透過鏟子選取陣法的細節嗎?今天來聊聊選擇完細節後,怎麼判斷魔法陣有沒有異常!」

「好唷~洗耳恭聽!」

「咦,感知到異常了!」

「這麼快在哪裡?」

「這裡!」艾草默默將毛茸茸的鳥翅膀指向了我。

「#@&^@*#&^(#@&^」
https://ithelp.ithome.com.tw/upload/images/20220923/20139066GDIPWcEDgR.png


上一篇提到如何透過 React Testing Library 選取 dom 元素,這篇要提到 @testing-library/jest-dom 套件庫, Jest DOM 提供了很多針對 Jest 測試網頁上 DOM 元素狀態的匹配器。

Jest DOM 的 Logo 是一隻可愛的貓頭鷹。

https://ithelp.ithome.com.tw/upload/images/20220923/20139066aqogiXj77b.png

來看看 Jest DOM 能做什麼吧!

Jest DOM

toBeInTheDocument

透過 toBeInTheDocument() 可以幫助判斷頁面上是否存在該元素。

假使頁面上有 Hello World!! 就可以透過此方式去斷言是否存在:

expect(getByText('Hello World!!')).toBeInTheDocument();

toBeDisabled

toBeDisabled() 可以判斷是否被禁用,以按鈕來舉例:

<button type="button" disabled>click</button>
// 透過 getByRole 選取 button 後判斷是否被禁用
expect(getByRole('button')).toBeDisabled()

當然還有其他可以被禁用的屬性可參考此文件

toBeEnabled

如果今天是想判斷是否未被禁用那就可以透過 toBeEnabled() 的方式,或直接在 toBeDisabled() 前加上 not 去判斷。

// 判斷未被禁用

// 1 使用 toBeEnabled
expect(getByRole('button')).toBeEnabled()

// 2 使用 toBeDisabled 搭配 not
expect(getByRole('button')).not.toBeDisabled()

toHaveStyle

toHaveStyle() 可確認元素是否擁有 style 設定值,可傳入 css 字串或物件,需要與帶入的值完全匹配才能通過。

要留意只有 Inline style 可以測, className 內設定的 css 樣式需要另外安裝套件才能測試。

以下程式碼範例取自 Jest dom 官方文件:

<button
  data-testid="delete-button"
  style="display: none; background-color: red"
>
  Delete item
</button>
const button = getByTestId('delete-button')

expect(button).toHaveStyle('display: none')
expect(button).toHaveStyle({display: 'none'})
expect(button).toHaveStyle(`
  background-color: red;
  display: none;
`)
expect(button).toHaveStyle({
  backgroundColor: 'red',
  display: 'none',
})
expect(button).not.toHaveStyle(`
  background-color: blue;
  display: none;
`)
expect(button).not.toHaveStyle({
  backgroundColor: 'blue',
  display: 'none',
})

與表單相關

toBeChecked

toBeChecked() 能檢查:

  • input type 為 checkboxradio 時是否有屬性 checked
  • 自行設定 rolecheckboxradioswitch ,且擁有 aria-checkedtrue

以下程式碼範例取自 Jest dom 官方文件:

// 情況一
// input type 為 checkbox 或 radio
// 會判斷是否有 checked 
// 1 checkbox 有 checked
<input type="checkbox" checked data-testid="input-checkbox-checked" />
const inputCheckboxChecked = getByTestId('input-checkbox-checked')
expect(inputCheckboxChecked).toBeChecked()
// 2 radio 無 checked
<input type="radio" value="foo" data-testid="input-radio-unchecked" />
const ariaRadioUnchecked = getByTestId('aria-radio-unchecked')
expect(ariaRadioUnchecked).not.toBeChecked()

// 情況二
// 自行設定 role 為 checkbox 、 radio 、 switch 
// 會判斷設置 aria-checked 為 true 或 false 
// 1 role="radio" 且 aria-checked 設定為 "true"
<div role="radio" aria-checked="true" data-testid="aria-radio-checked" />
const ariaRadioChecked = getByTestId('aria-radio-checked')
expect(ariaRadioChecked).toBeChecked()
// 2 role="switch" 而 aria-checked 設定為 "false"
<div role="switch" aria-checked="false" data-testid="aria-switch-unchecked" />
const ariaSwitchUnchecked = getByTestId('aria-switch-unchecked')
expect(ariaSwitchUnchecked).not.toBeChecked()

toBeRequired

toBeRequired() 判斷是否必填,判斷當表單元素是否有 requiredaria-required="true"

以下程式碼範例取自 Jest dom 官方文件:

// 1 包含 required
<input data-testid="required-input" required />
expect(getByTestId('required-input')).toBeRequired()

// 2 包含 aria-required="true"
<input data-testid="aria-required-input" aria-required="true" />
expect(getByTestId('aria-required-input')).toBeRequired()

// 3 包含 required 但 aria-required 為 "false" ,仍為必填
<input data-testid="conflicted-input" required aria-required="false" />
expect(getByTestId('conflicted-input')).toBeRequired()

toBeValid

toBeValid() 判斷用戶輸入後的值是否有效,當 aria-invalidfalse 或未設置值時,該值為有效,文件中有特別提到在使用時 checkValidity() 也必須為 true。

checkValidity() 為 form 表單提供的驗證方法,會用來檢查表單元素是否有要檢核的條件,如果通過時會回傳 true 。

以下程式碼範例取自 Jest dom 官方文件:

// 值為有效的情況
// 1 未設置 aria-invalid 時判斷該值為有效
<input data-testid="no-aria-invalid" />
expect(getByTestId('no-aria-invalid')).toBeValid()

// 2 設置 aria-invalid 為 "false" 時
<input data-testid="aria-invalid-false" aria-invalid="false" />
expect(getByTestId('aria-invalid-false')).toBeValid()

// 3 form 表單未設置需驗證屬性時
<form data-testid="valid-form">
  <input />
</form>
expect(getByTestId('valid-form')).toBeValid()

// 值為無效的情況
// 1 設置 aria-invalid 屬性時(預設為 true)
<input data-testid="aria-invalid" aria-invalid />
<input data-testid="aria-invalid-value" aria-invalid="true" />
expect(getByTestId('aria-invalid')).not.toBeValid()
expect(getByTestId('aria-invalid-value')).not.toBeValid()

// 2 設置驗證屬性時
<form data-testid="invalid-form">
  <input required />
</form>
expect(getByTestId('invalid-form')).not.toBeValid()

toBeInvalid

除了確認是否有效的屬性外也有 toBeInvalid() 可判斷表單輸入的值是否為無效,當 aria-invalid="true" 時該值為無效,且 checkValidity() 為 false。

所以上方案例除了可以使用 not 搭配 toBeValid 來判斷無效的值外也可改為透過 toBeInvalid()

// 值為無效的情況
// 1 設置 aria-invalid 屬性時(預設為 true)
<input data-testid="aria-invalid" aria-invalid />
<input data-testid="aria-invalid-value" aria-invalid="true" />
expect(getByTestId('aria-invalid')).toBeInvalid()
expect(getByTestId('aria-invalid-value')).toBeInvalid()

// 2 設置驗證屬性時
<form data-testid="invalid-form">
  <input required />
</form>
expect(getByTestId('invalid-form')).toBeInvalid()

toHaveErrorMessage

當有設定錯誤訊息 aria-errormessage 且表單值為無效時 aria-invalid="true" 可透過 toHaveErrorMessage() 進行測試,該測試是區分大小寫的,如果不想區分大小寫,可以使用正則表達式。

除了以上介紹到的之外 jest-dom 裡也有許多能確認表單預設值及展示值等匹配器如: toHaveValuetoHaveDisplayValuetoHaveFormValues ,如果有需要隨時都能透過 Jest DOM 替我們執行測試比對。


參考文章

https://github.com/testing-library/jest-dom
https://testing-library.com/docs/queries/about/


上一篇
React Testing Library 的一些好用選取方法
下一篇
情境練習:打勾才能按確認按鈕
系列文
<< 測試魔法 >> 這能動嗎?不然就測測看好了!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言